/*
 * timermgt.h
 *
 *  Created on: 2011-3-19
 *      Author: minorityee
 */

#ifndef TIMERMGT_H_
#define TIMERMGT_H_

#include "timer.h"
#include "common/common_def.h"
#include "common/common_type.h"
#include "common/common_object.h"
#include <assert.h>
#include <map>
#include <utility>
#ifndef WIN32
	#include <ext/hash_map>
	#include <ext/pool_allocator.h>
#else
	#include <hash_map>
#endif


/*  TimerIDList(RB-Tree)        TimerMap(hash table)
 *  _____________________        ___________________
 * |*most recent timerID |      | #2CTimer          |
 * | #1timerID           |      | #1CTimer          |
 * | #2timerID           |      |*most recent CTimer|
 * | #3timerID           |      | #4CTimer          |
 * | #4timerID           |      |                   |
 * |_____________________|      | #3CTimer          |
 *
 */

enum
{
	enmInvalidTimerID	= 0,
};

class CTimerMgt
{
public:
	typedef uint32_t TimerID;
	typedef __gnu_cxx ::hash_map<TimerID, Timer, __gnu_cxx::hash<TimerID>, __gnu_cxx::equal_to<TimerID>, __gnu_cxx::__pool_alloc<Timer> > TimerMap; // Warning: hash_map is not in std currently (but does provided by GNU C++ compiler and Microsoft's Visual C++)
	typedef std::multimap<int64_t, TimerID, std::less<int64_t>, __gnu_cxx::__pool_alloc<std::pair<const int64_t, TimerID> > > TimerIDList;
public:
	CTimerMgt() : nCurrTimerIDMapped_(0)
	{
	}
	~CTimerMgt()
	{
	}

	int32_t Initialize()
	{
		return S_OK;
	}

	int32_t Uninitialize()
	{
		return S_OK;
	}

	TimerID SetTimer(int enmTimerType, int nOwnerID, int64_t nCycleTime,
			bool bIsTimerCycle, int nAtt0, int nAtt1);

	/* return the Timer ID of the most recent timer (fired or not)
	 * return enmInvalidTimerID if timer list is empty
	 * */
	TimerID GetFirstTimer() const
	{
		TimerIDList::const_iterator citr = timerIDList_.begin();
		if (timerIDList_.end() != citr)
		{
			return citr->second;
		}
		return enmInvalidTimerID;
	}

	int32_t IsTimerCycle(const TimerID& timerID, bool& result) const
	{
		TimerMap::const_iterator citr = timerMap_.find(timerID);
		if (timerMap_.end() == citr)
		{
			return S_FALSE;
		}
		result = citr->second.bIsTimerCycle;
		return S_OK;
	}
	int32_t GetTimer(const TimerID& timerID, Timer& timer);
	int32_t TimerFired(const TimerID& timerID);
	int32_t DestoryTimer(const TimerID& timerID);
private:
	TimerIDList::iterator _FindTimerIDByEndTime(int64_t nEndTime, const TimerID& timerID);
private:
	TimerID 	nCurrTimerIDMapped_;
	TimerMap 	timerMap_;
	TimerIDList timerIDList_;
};

#endif /* TIMERMGT_H_ */
